package com.cf.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 发送请求到外网公共服务平台工具类
 *
 * @Author wangzc
 * @Date 2018/12/28 13:47
 * @Description
 */
public class HttpClientUtil {
    protected static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    public final static String METHOD_GET = "GET";
    public final static String METHOD_PUT = "PUT";
    public final static String METHOD_DELETE = "DELETE";
    public final static String METHOD_POST = "POST";

    /**
     * @param serviceUrl 请求的url
     * @param parameter  请求的参数
     * @return
     */
    public static String sendHttpRequest(String serviceUrl, String parameter) {
        String restMethod = "POST";
        String contentType = "application/json;charset=utf-8";

        HttpURLConnection con = null;
        BufferedReader in = null;
        String resultStr = "";

        try {
            logger.debug("rest request url:" + serviceUrl);
            logger.debug("url params:" + serviceUrl);
            URL url = new URL(serviceUrl);
            trustAllHttpsCertificates();
            //todo 这行不知道为什么new THostnameVerifier()会报错，这个工具类的代码是从明德直接复制过来的，以后用到的时候排查
//            HttpsURLConnection.setDefaultHostnameVerifier(new THostnameVerifier());
            con = (HttpURLConnection) url.openConnection();
            if (contentType == null || "".equals(contentType)) {
                contentType = "application/json;charset=utf-8";
            }
            //application/x-www-form-urlencoded
            con.setRequestProperty("Content-Type", contentType);
            con.setRequestMethod(restMethod);
            //如果请求方法为PUT,POST和DELETE设置DoOutput为真
            if (!HttpClientUtil.METHOD_GET.equals(restMethod)) {
                con.setDoOutput(true);
                con.setDoInput(true);
                //请求方法为PUT或POST时执行
                if (!HttpClientUtil.METHOD_DELETE.equals(restMethod)) { 
                    if (parameter != null) {
                        byte[] data = parameter.getBytes("UTF-8");
                        con.setRequestProperty("Content-Length", String.valueOf(data.length));
                        OutputStream os = con.getOutputStream();
                        con.setConnectTimeout(5 * 1000);
                        os.write(data);
                        os.flush();
                        os.close();
                    }
                }
            }
            StringBuffer buffer = new StringBuffer();

            in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
            String line = "";
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }
            in.close();
            resultStr = buffer.toString();

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (con != null) {
                con.disconnect();
                con = null;
            }
        }
        return resultStr;
    }

    /************************以下是解决https私钥不合法的问题 开始****************************/

    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                .getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc
                .getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
            return;
        }

        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
            return;
        }
    }
    /************************以下是解决https私钥不合法的问题 结束****************************/
}